package com.scedu.service.impl;

import com.scedu.convert.OrderDetail2CartDTOConverter;
import com.scedu.convert.OrderMaster2OrderDTOConverter;
import com.scedu.domain.OrderDetail;
import com.scedu.domain.OrderMaster;
import com.scedu.domain.ProductInfo;
import com.scedu.dto.CartDTO;
import com.scedu.dto.OrderDTO;
import com.scedu.enums.OrderStatusEnums;
import com.scedu.enums.PayStatusEnums;
import com.scedu.enums.ResultEnums;
import com.scedu.exception.SellException;
import com.scedu.repository.OrderDetailRepository;
import com.scedu.repository.OrderMasterRepository;
import com.scedu.service.OrderService;
import com.scedu.utils.KeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service //业务层
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderMasterRepository orderMasterRepository;
    @Autowired
    OrderDetailRepository orderDetailRepository;
    @Autowired
    ProductInfoServiceImpl productInfoService;
    @Autowired
    PayServiceImpl payService;
    @Override
    @Transactional
    public OrderDTO create(OrderDTO orderDTO) {
        //创建订单
        //1. 查询商品（数量，单价）
        //2. 计算总价
        //3. 写入订单数据库两个表（订单表 ordermaster 和 订单详情表 orderdetail
        //4. 如果下单成功，扣库存

//        name: "张三"
//        phone: "18868822111"
//        address: "慕课网总部"
//        openid: "ew3euwhd7sjw9diwkq" //用户的微信openid
//        items: [{
//            productId: "1423113435324",
//                    productQuantity: 2 //购买数量
//        }]

        BigDecimal orderAmout =new BigDecimal(0); //订单总价
        String orderId=KeyUtil.genUniqueKey(); //生成订单id

        //List<CartDTO> cartDTOList=new ArrayList<>(); //购物车队列 //生成购物车队列方法一

        //1. 查询商品（数量，单价）

       for (OrderDetail orderDetail:orderDTO.getOrderDetailList())
       {
           ProductInfo productInfo= productInfoService.findone(orderDetail.getProductId());
           if (productInfo==null){
               //如果商品信息为空，抛出异常
                throw  new SellException(ResultEnums.PRODUCT_NOT_EXIT_ERROR);
           }
           //2. 计算某一笔订单总价
           orderAmout=orderAmout
                   .add(productInfo.getProductPrice()
                           .multiply( new BigDecimal(orderDetail.getProductQuantity()))); //商品单价 *商品数量
           //订单详情入库
           //           orderDetail.setProductPrice(productInfo.getProductPrice());
//           orderDetail.setProductName(productInfo.getProductName());
//           orderDetail.setProductIcon(productInfo.getProductIcon());
           //精简写法 属性拷贝 空属性也会拷贝，必须放在第一行执行
           BeanUtils.copyProperties(productInfo,orderDetail); //Object source, Object target
           orderDetail.setOrderId(orderId);//生成订单ID
           orderDetail.setDetailId(KeyUtil.genUniqueKey());//生成订单详情id


           orderDetailRepository.save(orderDetail);//3. 写入订单数据库两个表（ 订单详情表 orderdetail)

           //生成购物车队列方法一
//           CartDTO cartDTO=new CartDTO(orderDetail.getProductId(),orderDetail.getProductQuantity());
//           cartDTOList.add(cartDTO);

       }

        OrderMaster orderMaster=new OrderMaster();
        //精简写法 属性拷贝 空属性也会拷贝，必须放在第一行执行
        BeanUtils.copyProperties(orderDTO,orderMaster); //Object source, Object target

        orderMaster.setOrderId(orderId);
        orderMaster.setOrderStatus(OrderStatusEnums.NEW.getCode());
        orderMaster.setPayStatus(PayStatusEnums.NOTPAYED.getCode());
        orderMaster.setOrderAmount(orderAmout); //3. 写入订单数据库两个表（订单表 ordermaster )

        orderMasterRepository.save(orderMaster);

        //4. 如果下单成功，扣库存

        List<CartDTO> cartDTOList=new ArrayList<>(); //购物车队列 //生成购物车队列方法二

        //DetailList().stream().map(e->).collect(Collectors.toList());
        cartDTOList =orderDTO.getOrderDetailList().stream().map(e->
                new CartDTO(e.getProductId(),e.getProductQuantity()
                )).collect(Collectors.toList());

        productInfoService.dereaseStock(cartDTOList);
        return OrderMaster2OrderDTOConverter.convert(orderMaster);
    }

    @Override
    public OrderDTO findOne(String orderID) {
        OrderMaster orderMaster= orderMasterRepository.findById(orderID).orElse(null);
        if (orderMaster==null){
            throw new SellException(ResultEnums.ORDER_NOT_EXIT_ERROR);
        }

        List<OrderDetail> orderDetailList=orderDetailRepository.findByOrderId(orderID);
        if (CollectionUtils.isEmpty((orderDetailList))){
            //判断队列是否为空
            throw new SellException(ResultEnums.ORDERS_NOT_EXIT_ERROR);
        }
        OrderDTO orderDTO=new OrderDTO();
        BeanUtils.copyProperties(orderMaster,orderDTO);
        orderDTO.setOrderDetailList(orderDetailList);
        return orderDTO;
    }

    @Override
    public Page<OrderDTO> findList(String buyerOpenid, Pageable pageable) {
        Page<OrderMaster> orderMastes= orderMasterRepository.findByOrderOpenid(buyerOpenid,pageable);
        List<OrderDTO> ordrDTOs= OrderMaster2OrderDTOConverter.convert(orderMastes.getContent());

        Page<OrderDTO> orderDTOPage=new PageImpl<OrderDTO>(ordrDTOs,pageable,orderMastes.getTotalElements());
        return orderDTOPage;
    }

//    public Page<OrderDTO> findList(String buyerOpenid, Pageable pageable) {
//        //自己写的
//        List<OrderMaster> orderMastes= orderMasterRepository.findByOrderOpenid(buyerOpenid,pageable).toList();
//        List<OrderDTO> ordrDTOs=new ArrayList<>();
//
//        for (OrderMaster orderMaster:orderMastes){
//            String orderID=orderMaster.getOrderId();
//            List<OrderDetail> orderDetailList=orderDetailRepository.findByOrderId(orderID);
//            if (CollectionUtils.isEmpty((orderDetailList))){
//                //判断队列是否为空
//                throw new SellException(ResultEnums.ORDERS_NOT_EXIT_ERROR);
//            }
//            OrderDTO orderDTO=new OrderDTO();
//            BeanUtils.copyProperties(orderMaster,orderDTO);
//            orderDTO.setOrderDetailList(orderDetailList);
//            ordrDTOs.add(orderDTO);
//        }
//
//        Page<OrderDTO> orderDTOPage=new PageImpl<OrderDTO>(ordrDTOs);
//        return orderDTOPage;
//    }

    @Override
    @Transactional
    public OrderDTO cancel(OrderDTO orderDTO) {
        //取消订单
        // openid: 18eu2jwk2kse3r42e2e
        //orderId: 161899085773669363


        //1.判断订单状态 非新订单不能修改

        if (!orderDTO.getOrderStatus().equals(OrderStatusEnums.NEW.getCode())){
            //不等于0,不可以取消
            log.error("取消订单状态不正确，orderid={}",orderDTO.getOrderId());
            throw new SellException(ResultEnums.ORDERS_STATUS_ERROR);
        }


        //2.修改订单状态
        OrderMaster orderMaster=new OrderMaster();
        BeanUtils.copyProperties(orderDTO,orderMaster);
        orderMaster.setOrderStatus(OrderStatusEnums.CANCEL.getCode());
        OrderMaster updateresult= orderMasterRepository.save(orderMaster);
        if (updateresult==null){
            log.error("更新失败，ordermaster={}",updateresult);
            throw new SellException(ResultEnums.ORDERS_UPDATE_ERROR);
        }
        //3.修改库存
        if(CollectionUtils.isEmpty(orderDTO.getOrderDetailList())){
            log.error("订单中无商品");
            throw new SellException(ResultEnums.ORDERS_DETAILNULL_ERROR);
        }
//         List<CartDTO> cartDTOList=orderDTO.getOrderDetailList().stream().map(e->
//                new CartDTO (e.getProductId(),e.getProductQuantity())
//         ).collect(Collectors.toList());
        List<CartDTO> cartDTOList=OrderDetail2CartDTOConverter.convert(orderDTO.getOrderDetailList());
        productInfoService.inreaseStock(cartDTOList);

        //4.如果已支付完成，退款给用户
        if(orderDTO.getPayStatus().equals(PayStatusEnums.PAYED.getCode())){

            payService.refund(orderDTO); //退款
        }
        orderDTO.setOrderStatus(OrderStatusEnums.CANCEL.getCode());
        return orderDTO;
    }

    @Override
    @Transactional
    public OrderDTO finish(OrderDTO orderDTO) {
        //订单完成
        //1.判断订单状态 非新订单不能修改

        if (!orderDTO.getOrderStatus().equals(OrderStatusEnums.NEW.getCode())){
            //不等于0,不可以取消
            log.error("完成订单状态不正确，orderid={}",orderDTO.getOrderId());
            throw new SellException(ResultEnums.ORDERS_STATUS_ERROR);
        }
        //2.修改订单状态
        OrderMaster orderMaster=new OrderMaster();
        BeanUtils.copyProperties(orderDTO,orderMaster);
        orderMaster.setOrderStatus(OrderStatusEnums.FINISH.getCode());
        OrderMaster updateresult= orderMasterRepository.save(orderMaster);
        if (updateresult==null){
            log.error("更新失败，ordermaster={}",updateresult);
            throw new SellException(ResultEnums.ORDERS_UPDATE_ERROR);
        }
        orderDTO.setOrderStatus(OrderStatusEnums.FINISH.getCode());
        return orderDTO;
    }

    @Override
    @Transactional
    public OrderDTO payed(OrderDTO orderDTO) {
        //订单支付状态
        //1.判断订单状态 非新订单不能修改
        if (!orderDTO.getOrderStatus().equals(OrderStatusEnums.NEW.getCode())){
            //不等于0,不可以取消
            log.error("完成订单状态不正确，orderid={}",orderDTO.getOrderId());
            throw new SellException(ResultEnums.ORDERS_STATUS_ERROR);
        }
        //1a.判断订单支付状态 非未支付不能修改

        if (!orderDTO.getPayStatus().equals(PayStatusEnums.NOTPAYED.getCode())){
            //不等于0,不可以取消
            log.error("订单支付状态不正确，orderid={}",orderDTO.getOrderId());
            throw new SellException(ResultEnums.ORDERS_STATUS_ERROR);
        }
        //修改订单状态
        //2.修改订单状态
        OrderMaster orderMaster=new OrderMaster();
        BeanUtils.copyProperties(orderDTO,orderMaster);
        orderMaster.setPayStatus(PayStatusEnums.PAYED.getCode());
        OrderMaster updateresult= orderMasterRepository.save(orderMaster);
        if (updateresult==null){
            log.error("更新失败，ordermaster={}",updateresult);
            throw new SellException(ResultEnums.ORDERS_UPDATE_ERROR);
        }

        orderDTO.setPayStatus(PayStatusEnums.PAYED.getCode());
        return orderDTO;
    }

    @Override
    public Page<OrderDTO> findList(Pageable pageable) {
        Page<OrderMaster> orderMastes= orderMasterRepository.findAll(pageable);
        List<OrderDTO> ordrDTOs= OrderMaster2OrderDTOConverter.convert(orderMastes.getContent());

        Page<OrderDTO> orderDTOPage=new PageImpl<OrderDTO>(ordrDTOs,pageable,orderMastes.getTotalElements());
        return orderDTOPage;
    }
}
